/*
 * NativeTestCase.cpp  0.4.0 / Nov 5, 2010
 *
 * Copyright (c) 2010 - 2011, cute4j.com and contributors.
 *
 * This software is licensed under the LGPL version 2.1 license.
 * A copy of this license is included in the file LICENSE-LGPL.txt.
 */
#include "NativeTestCase.h"

#ifdef CUTE4J_TEST

// NativeTestCase :: Public Constructor. ---------------------------------------

/*!
 * \brief Constructs new NativeTestCase object.
 *
 * \param env the JNIEnv pointer
 * \param obj the NativeTestCase object
 */
NativeTestCase::NativeTestCase(JNIEnv *env, jobject obj)
  : m_env(env)
{
  Q_ASSERT(env);
  Q_ASSERT(obj);
  m_obj = env->NewWeakGlobalRef(obj);
  if (env->ExceptionCheck()) { // check for OutOfMemoryError
    env->ExceptionDescribe();
    env->ExceptionClear();
  }
}

// NativeTestCase :: Public Destructor. ----------------------------------------

/*!
 * \brief Destructs NativeTestCase object.
 */
NativeTestCase::~NativeTestCase()
{
  if (m_obj) {
    m_env->DeleteWeakGlobalRef(m_obj);
  }
}

// NativeTestCase :: Public Static Member Functions. ---------------------------

/*!
 * \brief Initializes NativeTestCase class.
 *
 * \param env the JNIEnv pointer
 * \param cls the NativeTestCase class
 *
 * \exception FatalError if failed
 */
void NativeTestCase::initialize(JNIEnv *env, jclass cls)
{
  Q_ASSERT(env);
  Q_ASSERT(cls);
  Q_ASSERT(!sm_testObjectFID);
  if (!INIT_UFID(testObject, cls, "J") ||
      !INIT_MID(failCondition, cls,
                "(Ljava/lang/String;Ljava/lang/String;I)V")) {
    env->FatalError("NativeTestCase initialization failed"); // does not return
  }
}

/*!
 * \brief Returns test object pointer.
 *
 * \param env the JNIEnv pointer
 * \param obj the NativeTestCase subclass object
 *
 * \return test object pointer
 */
jlong NativeTestCase::testObject(JNIEnv *env, jobject obj)
{
  Q_ASSERT(env);
  Q_ASSERT(obj);
  return env->GetLongField(obj, sm_testObjectFID);
}

// NativeTestCase :: Protected Method. -----------------------------------------

/*!
 * \brief Fails condition.
 *
 * \param condition the condition
 * \param fileName the file name
 * \param lineNumber the line number
 */
void NativeTestCase::failCondition(const char *condition, const char *fileName,
                                   int lineNumber)
{
  Q_ASSERT(m_env);
  Q_ASSERT(m_obj);
  jstring jcondition = 0;
  jstring jfileName = 0;
  if (condition) {
    jcondition = m_env->NewStringUTF(condition);
    Q_ASSERT(jcondition);
  }
  if (fileName) {
    jfileName = m_env->NewStringUTF(fileName);
    Q_ASSERT(jfileName);
  }
  m_env->CallVoidMethod(m_obj, sm_failConditionMID, jcondition, jfileName,
                        lineNumber);
}

// NativeTestCase :: Private Static Data Member. -------------------------------

jfieldID NativeTestCase::sm_testObjectFID = 0;
jmethodID NativeTestCase::sm_failConditionMID = 0;

#endif // CUTE4J_TEST
